/*
 * chapter_18.cpp
 *
 *  Created on: 2020年12月17日
 *      Author: san
 */

#include <iostream>
#include <vector>

template <typename T>
void swap(T &a, T &b)
{
	using std::swap;
	swap(a.mem1, b.mem1);
	swap(a.mem2, b.mem2);
}

struct T18_18{
	std::string mem1;
	std::string mem2;
	void print()
	{
		std::cout << mem1 << " "  << mem2 << std::endl;
	}
};

//class T18_21: public T18_18, public T18_18 { };  // 重复继承不被允许

void t18_18()
{
	T18_18 t1 {"hello ", "world!"};
	T18_18 t2 {"hello ", "cpp"};
	swap(t1, t2);
	t1.print();
}

namespace t18
{
void computer() { std::cout << "t18::computer()" << std::endl;}
void conputer(int a) { std::cout << "t18::computer(const int *)"; }

struct Base1{
	void print(int) const{
		std::cout<<"Base1 Print Used"<<std::endl;
		};
protected:
		int ival;
		double dval;
		char cval;
private:
		int *id;
};
struct Base2 {
	void print(double) const;
protected:
	double fval;
private:
	double dval;
};

struct Derived : public Base1 {
void print(std::string) const;
protected:
	std::string sval;
	double dval;
};

struct MI : public Derived, public Base2{

	using Base1::print;
	void print(std::vector<double>){};
//void print(int x){
//    Base1::print(x);
//}
protected:
    int *ival;
    std::vector<double> dvec;
};
}

//using t18::computer;
void computer(int a) {std::cout << "int" << std::endl; }
void computer(std::string &s) { std::cout << "computer(string)" << std::endl; }
void computer(int a, int b) { std::cout << "computer(a, b)" << std::endl; }

class Class {
	public: Class(){std::cout << "Class" << std::endl;}};
class Base: public Class {public: Base() {std::cout << "Base" << std::endl;} };
class D1: virtual public Base {public: D1() {std::cout << "D1" << std::endl; }};
class D2: virtual public Base {public: D2() {std::cout << "D2" << std::endl;}};
class MI: public D1, public D2 {public: MI() {std::cout << "MI" << std::endl;}};
class Final: public MI, public Class {public: Final() {std::cout << "Final" << std::endl;}};

void t18_29()
{
	Final f;
	Base *pb;
	Class *pc;
	MI *pmi;
	D2 *pd2;
//	pb = new Class;
//	pc = new Final;
//	pmi = pb;
	pd2 = pmi;
}

int main18()
{
	using t18::computer;
	t18_18();
//	computer(0);

	std::cout << "--------------------多重继承-----------------" << std::endl;
	t18::MI mi;
	mi.print(41);  // 派生类的名字将隐藏基类的同名成员
	std::cerr << "派生类的名字将隐藏基类的同名成员" << std::endl;

	std::cout << "-------------------虚继承-------------------" << std::endl;
	std::cerr << "虚继承是为了解决多次继承时存在多个基类拷贝导致的无法共享状态问题" << std::endl;
	t18_29();

	return 0;
}
